class DoubleLinkedList {
    // 头节点不要动 不存放具体数据
    head = new HeroNode(0, '', '')

    // 返回头节点
    head () {
        return this.head
    }

    // 遍历链表
    list () {
        if (this.head.next === null) {
            console.log('链表为空')
            return
        }
        let temp = this.head.next
        while (true) {
            if (temp === null) {
                break
            }
            console.log(temp.toString())
            temp = temp.next
        }
    }

    /**
     *
     * @param heroNode {HeroNode}
     */
    add (heroNode) {
        let temp = this.head
        // 找到链表的最后一个节点
        while (true) {
            if (temp.next === null) {
                break
            }
            temp = temp.next
        }
        temp.next = heroNode
        heroNode.pre = temp
    }

    /**
     *  按no顺序添加
     * @param heroNode {HeroNode}
     */
    addByOrder (heroNode) {
        let temp = this.head
        let flag = false // 添加的编号是否存在

        while (true) {
            if (temp.next === null) { // 说明已经在链表的最后
                break
            }
            if (temp.next.no > heroNode.no) { // 找到位置
                break
            } else if (temp.next.no === heroNode.no) { // 说明编号存在
                flag = true
                break
            }
            temp = temp.next
        }
        if (flag) {
            console.log('编号已经存在')
        } else {
            heroNode.next = temp.next
            heroNode.pre = temp
            if (temp.next !== null) {
                temp.next.pre = heroNode
            }
            temp.next = heroNode
        }
    }

    /**
     * 根据NO修改节点信息 双向链表的修改与单向链表德 修改一样
     * @param newHeroNode {HeroNode}
     */
    update (newHeroNode) {
        if (this.head.next === null) {
            console.log('链表为空')
            return
        }
        let temp = this.head.next
        let flag = false // 是否找到该节点
        while (true) {
            if (temp === null) {
                break
            }
            if (temp.no === newHeroNode.no) {
                flag = true
                break
            }
            temp = temp.next
        }
        if (flag) {
            temp.name = newHeroNode.name
            temp.nickname = newHeroNode.nickname
        } else {
            console.log('没有找到该节点')
        }
    }

    /**
     * 根据no删除节点
     * @param no {number}
     */
    delete (no) {
        if (this.head.next === null) {
            console.log('链表为空')
            return
        }
        let temp = this.head.next
        let flag = false // 是否找到该节点
        while (true) {
            if (temp === null) {
                break
            }
            if (temp.no === no) {
                flag = true
                break
            }
            temp = temp.next
        }
        if (flag) {
            temp.pre.next = temp.next
            if (temp.next !== null) { // 如果是最后一个节点 就不需要
                temp.next.pre = temp.pre
            }

        } else {
            console.log('没有找到该节点')
        }
    }

}

class HeroNode {
    no = ''
    name = ''
    nickname = ''
    next = null // 指向下一个节点
    pre = null  // 指向上一个节点

    /**
     *
     * @param no {number}
     * @param name {string}
     * @param nickname {string}
     */
    constructor (no, name, nickname) {
        this.no = no
        this.name = name
        this.nickname = nickname
    }

    toString () {
        return `HeroNode [no=${this.no},name=${this.name},nickname=${this.nickname}]`
    }
}

function test () {
    let hero1 = new HeroNode(1, '宋江', '及时雨')
    let hero2 = new HeroNode(2, '卢俊义', '玉麒麟')
    let hero3 = new HeroNode(3, '吴用', '智多星')
    let hero4 = new HeroNode(4, '林冲', '豹子头')

    let doubleLinkedList = new DoubleLinkedList()

    // console.log('测试-添加')
    // doubleLinkedList.add(hero1)
    // doubleLinkedList.add(hero2)
    // doubleLinkedList.add(hero3)
    // doubleLinkedList.add(hero4)
    // doubleLinkedList.list()

    console.log('测试-顺序添加')
    doubleLinkedList.addByOrder(hero3)
    doubleLinkedList.addByOrder(hero4)
    doubleLinkedList.addByOrder(hero1)
    doubleLinkedList.addByOrder(hero2)
    doubleLinkedList.list()

    console.log('测试-修改')
    doubleLinkedList.update(new HeroNode(2, 'AA', 'AA'))
    doubleLinkedList.list()

    console.log('测试-删除')
    doubleLinkedList.delete(2)
    doubleLinkedList.list()
}

test()
